00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _hash_distr_hpp_
00023 #define _hash_distr_hpp_
00024
00025 #define SYSTOLIC
00026
00027
00028
00029 #include <ga.h>
00030 #include <boost/unordered_map.hpp>
00031 #include "gridpack/parallel/index_hash.hpp"
00032 #include "gridpack/utilities/exception.hpp"
00033
00034 namespace gridpack {
00035 namespace hash_distr {
00036
00037
00038
00039
00040 template <typename _network,
00041 typename _bus_data_type,
00042 typename _branch_data_type>
00043 class HashDistribution {
00044 private:
00045
00046 typedef struct{int idx;
00047 _bus_data_type data;
00048 } bus_data_pair;
00049
00050 typedef struct{int idx1;
00051 int idx2;
00052 _branch_data_type data;
00053 } branch_data_pair;
00054
00055 public:
00056 typedef _network NetworkType;
00057 typedef boost::shared_ptr<NetworkType> NetworkPtr;
00058
00059
00060
00061 HashDistribution(const boost::shared_ptr<_network> network)
00062 : p_network(network)
00063 {
00064 #ifndef SYSTOLIC
00065 p_indexHashMap.reset(new
00066 gridpack::hash_map::GlobalIndexHashMap(p_network->communicator()));
00067 #endif
00068 p_GAgrp = p_network->communicator().getGroup();
00069 int me = p_network->communicator().rank();
00070
00071 #ifndef SYSTOLIC
00072
00073 int i,ikey,ival,idx1,idx2;
00074 std::vector<std::pair<int,int> > busPairs;
00075 int nbus = p_network->numBuses();
00076 for (i=0; i<nbus; i++) {
00077 ikey = p_network->getOriginalBusIndex(i);
00078 ival = me;
00079 busPairs.push_back(std::pair<int,int>(ikey,ival));
00080 }
00081 p_indexHashMap->addPairs(busPairs);
00082 busPairs.clear();
00083 std::pair<int,int> key;
00084 std::vector<std::pair<std::pair<int,int>, int> >
00085 branchPairs;
00086 int nbranch = p_network->numBranches();
00087 for (i=0; i<nbranch; i++) {
00088 p_network->getOriginalBranchEndpoints(i,&idx1,&idx2);
00089 key = std::pair<int,int>(idx1,idx2);
00090 ival = me;
00091 branchPairs.push_back(std::pair<std::pair<int,int>,int>(key,ival));
00092 }
00093 p_indexHashMap->addPairs(branchPairs);
00094 branchPairs.clear();
00095 #endif
00096
00097
00098 p_size_bus_data = sizeof(bus_data_pair);
00099 p_size_branch_data = sizeof(branch_data_pair);
00100 }
00101
00102
00103 ~HashDistribution(void)
00104 {
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 void distributeBusValues(std::vector<int> &keys, std::vector<_bus_data_type> &values)
00116 {
00117 #ifdef SYSTOLIC
00118 int ksize = keys.size();
00119 int vsize = values.size();
00120 int me = GA_Pgroup_nodeid(p_GAgrp);
00121 int nprocs = GA_Pgroup_nnodes(p_GAgrp);
00122 if (vsize != ksize) {
00123 char buf[256];
00124 sprintf(buf,"p[%d] HashDistribution::distributeBusValues ERROR: length of"
00125 " keys and values arrays don't match ksize: %d vsize: %d\n",
00126 me,ksize,vsize);
00127 printf("%s",buf);
00128 throw gridpack::Exception(buf);
00129 }
00130
00131
00132 int i;
00133 int *sizes = new int[nprocs];
00134 for (i=0; i<nprocs; i++) {
00135 sizes[i] = 0;
00136 }
00137 sizes[me] = ksize;
00138 char plus[2];
00139 strcpy(plus,"+");
00140 GA_Pgroup_igop(p_GAgrp,sizes,nprocs,plus);
00141 int *mapc = new int[nprocs];
00142 mapc[0] = 0;
00143 int total_values = sizes[0];
00144 for (i=1; i<nprocs; i++) {
00145 mapc[i] = mapc[i-1]+sizes[i-1];
00146 total_values += sizes[i];
00147 }
00148 if (total_values == 0) {
00149 delete [] sizes;
00150 delete [] mapc;
00151 return;
00152 }
00153
00154
00155 bus_data_pair *list;
00156 if (ksize > 0) {
00157 list = new bus_data_pair[ksize];
00158 for (i=0; i<ksize; i++) {
00159 list[i].idx = keys[i];
00160 list[i].data = values[i];
00161 }
00162 }
00163 int g_type = NGA_Register_type(p_size_bus_data);
00164
00165
00166 int lo, hi;
00167 lo = 0;
00168 for (i=0; i<me; i++) {
00169 lo += sizes[i];
00170 }
00171 hi = lo + sizes[me] - 1;
00172 int one = 1;
00173 int g_vals = GA_Create_handle();
00174 GA_Set_data(g_vals,one,&total_values,g_type);
00175
00176 GA_Set_pgroup(g_vals,p_GAgrp);
00177 if (!GA_Allocate(g_vals)) {
00178 char buf[256];
00179 sprintf(buf,"HashDistribution::distributeBusValues: Unable to allocate"
00180 " distributed array for storing values");
00181 printf("%s",buf);
00182 throw gridpack::Exception(buf);
00183 }
00184 if (lo <= hi) NGA_Put(g_vals, &lo, &hi, list, &one);
00185 GA_Pgroup_sync(p_GAgrp);
00186 NGA_Deregister_type(g_type);
00187 if (ksize > 0) delete [] list;
00188 delete [] mapc;
00189 delete [] sizes;
00190
00191
00192 int idx;
00193 int nbus = p_network->numBuses();
00194 std::multimap<int,int> hmap;
00195 for (i=0; i<nbus; i++) {
00196 idx = p_network->getOriginalBusIndex(i);
00197 hmap.insert(std::pair<int,int>(idx,i));
00198 }
00199 std::multimap<int,int>::iterator it;
00200
00201
00202 keys.clear();
00203 values.clear();
00204 double delta = static_cast<double>(total_values)/static_cast<double>(nprocs);
00205 for (i = 0; i<nprocs; i++) {
00206 idx = (i+me)%nprocs;
00207 lo = static_cast<int>(delta*static_cast<double>(idx));
00208 if (idx<nprocs-1) {
00209 hi = static_cast<int>(delta*static_cast<double>(idx+1))-1;
00210 } else {
00211 hi = total_values-1;
00212 }
00213 int nsize = hi - lo + 1;
00214 if (lo <= hi) {
00215 list = new bus_data_pair[nsize];
00216 if (lo<=hi) NGA_Get(g_vals, &lo, &hi, list, &one);
00217 int j;
00218 for (j=0; j<nsize; j++) {
00219 it = hmap.find(list[j].idx);
00220 if (it != hmap.end()) {
00221 while (it != hmap.upper_bound(list[j].idx)) {
00222 keys.push_back(it->second);
00223 values.push_back(list[j].data);
00224 it++;
00225 }
00226 }
00227 }
00228 delete [] list;
00229 }
00230 }
00231 GA_Destroy(g_vals);
00232 #else
00233 int nprocs = p_network->communicator().size();
00234 int me = p_network->communicator().rank();
00235
00236 int i,j;
00237
00238 std::vector<int> base_keys;
00239 std::set<int> key_check;
00240 std::set<int>::iterator itc;
00241 for (i=0; i<keys.size(); i++) {
00242 itc = key_check.find(keys[i]);
00243 if (itc == key_check.end()) {
00244 key_check.insert(keys[i]);
00245 base_keys.push_back(keys[i]);
00246 }
00247 }
00248 std::vector<int> procLoc;
00249
00250 p_indexHashMap->getValues(base_keys,procLoc);
00251
00252
00253
00254 std::multimap<int,int> keyMap;
00255 for (i=0; i<base_keys.size(); i++) {
00256 keyMap.insert(std::pair<int,int>(base_keys[i],procLoc[i]));
00257 }
00258 std::vector<_bus_data_type> newValues;
00259 std::vector<int> newKeys;
00260 std::vector<int> destProcs;
00261 j = 0;
00262 std::multimap<int,int>::iterator itk;
00263 for (i=0; i<values.size(); i++) {
00264 itk = keyMap.find(keys[i]);
00265 if (itk != keyMap.end()) {
00266 while (itk != keyMap.upper_bound(keys[i])) {
00267 newValues.push_back(values[i]);
00268 newKeys.push_back(keys[i]);
00269 destProcs.push_back(itk->second);
00270 itk++;
00271 }
00272 }
00273 }
00274
00275
00276 int nsize = newKeys.size();
00277 int ltop[nprocs];
00278 int ldest[nsize];
00279 int destNum[nprocs];
00280 for (i=0; i<nprocs; i++) {
00281 ltop[i] = -1;
00282 destNum[i] = 0;
00283 }
00284 for (i=0; i<nsize; i++) {
00285 ldest[i] = -1;
00286 }
00287 int iproc;
00288 for (i=0; i<nsize; i++) {
00289 iproc = destProcs[i];
00290 destNum[iproc]++;
00291 ldest[i] = ltop[iproc];
00292 ltop[iproc] = i;
00293 }
00294 #ifdef HASH_WITH_MPI
00295
00296
00297 int srcNum[nprocs];
00298 int ierr;
00299 int one = 1;
00300 MPI_Comm comm = static_cast<MPI_Comm>(p_network->communicator());
00301 ierr = MPI_Alltoall(destNum,one,MPI_INT,srcNum,one,MPI_INT,comm);
00302
00303
00304
00305
00306 bus_data_pair *sendBuf;
00307 sendBuf = new bus_data_pair[newValues.size()];
00308
00309 int icnt=0;
00310 for (i=0; i<nprocs; i++) {
00311 j = ltop[i];
00312 if (j>=0) {
00313 while(j >= 0) {
00314 sendBuf[icnt].idx = newKeys[j];
00315 sendBuf[icnt].data = newValues[j];
00316 j = ldest[j];
00317 icnt++;
00318 }
00319 }
00320 }
00321
00322
00323
00324 int elemsize = sizeof(bus_data_pair);
00325 int destOffset[nprocs];
00326 int srcOffset[nprocs];
00327 destOffset[0] = 0;
00328 srcOffset[0] = 0;
00329 for (i=1; i<nprocs; i++) {
00330 destOffset[i] = destOffset[i-1] + destNum[i-1];
00331 srcOffset[i] = srcOffset[i-1] + srcNum[i-1];
00332 }
00333 int nvalues = 0;
00334 for (i=0; i<nprocs; i++) {
00335 nvalues += srcNum[i];
00336 destOffset[i] = elemsize*destOffset[i];
00337 destNum[i] = elemsize*destNum[i];
00338 srcOffset[i] = elemsize*srcOffset[i];
00339 srcNum[i] = elemsize*srcNum[i];
00340 }
00341
00342
00343 bus_data_pair *recvBuf;
00344 recvBuf = new bus_data_pair[nvalues];
00345
00346
00347 ierr = MPI_Alltoallv(sendBuf, destNum, destOffset, MPI_BYTE, recvBuf,
00348 srcNum, srcOffset, MPI_BYTE, comm);
00349 delete [] sendBuf;
00350
00351
00352
00353
00354 keys.clear();
00355 values.clear();
00356 int nbus = p_network->numBuses();
00357 std::multimap<int,int> idxMap;
00358 std::pair<int,int> idxPair;
00359
00360 for (i=0; i<nbus; i++) {
00361 idxPair = std::pair<int,int>(p_network->getOriginalBusIndex(i),i);
00362 idxMap.insert(idxPair);
00363 }
00364
00365
00366 std::multimap<int,int>::iterator it;
00367 for (i=0; i<nvalues; i++) {
00368 it = idxMap.find(recvBuf[i].idx);
00369 if (it != idxMap.end()) {
00370 while (it != idxMap.upper_bound(recvBuf[i].idx)) {
00371 keys.push_back(it->second);
00372 values.push_back(recvBuf[i].data);
00373 it++;
00374 }
00375 } else {
00376 printf("p[%d] Unresolved original bus index: %d\n",me,
00377 recvBuf[i].idx);
00378 }
00379 }
00380
00381 delete [] recvBuf;
00382 #else
00383
00384
00385 int g_numValues = GA_Create_handle();
00386 int dims;
00387 dims = nprocs;
00388 int one = 1;
00389 int blocks;
00390 blocks = 1;
00391 GA_Set_data(g_numValues,one,&dims,C_INT);
00392 GA_Set_chunk(g_numValues, &blocks);
00393 GA_Set_pgroup(g_numValues, p_GAgrp);
00394 GA_Allocate(g_numValues);
00395 GA_Zero(g_numValues);
00396 int r_offset[nprocs];
00397 for (j=0; j<nprocs; j++) {
00398 i = (j+me)%nprocs;
00399 if (destNum[i] > 0) {
00400 r_offset[i] = NGA_Read_inc(g_numValues,&i,destNum[i]);
00401 } else {
00402 r_offset[i] = 0;
00403 }
00404 }
00405 GA_Pgroup_sync(p_GAgrp);
00406
00407 int numValues[nprocs];
00408 int lo, hi;
00409 lo = 0;
00410 hi = nprocs-1;
00411 if (me == 0) {
00412 if (lo<=hi) NGA_Get(g_numValues,&lo,&hi,numValues,&one);
00413 } else {
00414 for (i=0; i<nprocs; i++) {
00415 numValues[i] = 0;
00416 }
00417 }
00418 char plus[2];
00419 strcpy(plus,"+");
00420 GA_Pgroup_igop(p_GAgrp,numValues,nprocs,plus);
00421 GA_Destroy(g_numValues);
00422
00423
00424
00425
00426 int dtype = NGA_Register_type(sizeof(bus_data_pair));
00427
00428 int totalVals = 0;
00429 for (i=0; i<nprocs; i++) {
00430 r_offset[i] += totalVals;
00431 totalVals += numValues[i];
00432 }
00433 if (totalVals == 0) {
00434 NGA_Deregister_type(dtype);
00435 return;
00436 }
00437 int g_data = GA_Create_handle();
00438 dims = totalVals;
00439 GA_Set_data(g_data, one, &dims, dtype);
00440 GA_Set_pgroup(g_data,p_GAgrp);
00441 int mapc[nprocs];
00442 mapc[0] = 0;
00443 for (i=1; i<nprocs; i++) {
00444 mapc[i] = mapc[i-1] + numValues[i-1];
00445 }
00446 blocks = nprocs;
00447 GA_Set_irreg_distr(g_data,mapc,&blocks);
00448 GA_Allocate(g_data);
00449
00450
00451 bus_data_pair *bus_data;
00452 int ncnt;
00453 for (i=0; i<nprocs; i++) {
00454 j = ltop[i];
00455 ncnt = 0;
00456 if (j >= 0) {
00457 bus_data = new bus_data_pair[destNum[i]];
00458 while (j >= 0) {
00459 bus_data[ncnt].idx = newKeys[j];
00460 bus_data[ncnt].data = newValues[j];
00461 j = ldest[j];
00462 ncnt++;
00463 }
00464 lo = r_offset[i];
00465 hi = lo + destNum[i] - 1;
00466 if (lo<=hi) NGA_Put(g_data,&lo,&hi,bus_data,&one);
00467 delete [] bus_data;
00468 }
00469 }
00470
00471 GA_Pgroup_sync(p_GAgrp);
00472
00473 keys.clear();
00474 values.clear();
00475 int nbus = p_network->numBuses();
00476 std::multimap<int,int> idxMap;
00477 std::pair<int,int> idxPair;
00478
00479 for (i=0; i<nbus; i++) {
00480 idxPair = std::pair<int,int>(p_network->getOriginalBusIndex(i),i);
00481 idxMap.insert(idxPair);
00482 }
00483
00484
00485 int ndata = numValues[me];
00486 lo = mapc[me];
00487 hi = lo + ndata - 1;
00488 if (lo<=hi) NGA_Access(g_data,&lo,&hi,&bus_data,&one);
00489 std::multimap<int,int>::iterator it;
00490 for (i=0; i<ndata; i++) {
00491 it = idxMap.find(bus_data[i].idx);
00492 if (it != idxMap.end()) {
00493 while (it != idxMap.upper_bound(bus_data[i].idx)) {
00494 keys.push_back(it->second);
00495 values.push_back(bus_data[i].data);
00496 it++;
00497 }
00498 } else {
00499 printf("p[%d] Unresolved original bus index: %d\n",me,
00500 bus_data[i].idx);
00501 }
00502 }
00503 if (lo<=hi) NGA_Release(g_data,&lo,&hi);
00504 GA_Destroy(g_data);
00505 #endif
00506 #endif
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 void distributeBusValues(std::vector<int> &keys, std::vector<_bus_data_type*>
00519 &values, int nvals)
00520 {
00521 #ifdef SYSTOLIC
00522 int ksize = keys.size();
00523 int vsize = values.size();
00524 int me = GA_Pgroup_nodeid(p_GAgrp);
00525 int nprocs = GA_Pgroup_nnodes(p_GAgrp);
00526 if (vsize != ksize) {
00527 char buf[256];
00528 sprintf(buf,"p[%d] HashDistribution::distributeBusValues ERROR: length"
00529 " of keys and values arrays don't match ksize: %d vsize: %d\n",
00530 me,ksize,vsize);
00531 printf("%s",buf);
00532 throw gridpack::Exception(buf);
00533 }
00534
00535
00536 int i, j;
00537 int *sizes = new int[nprocs];
00538 for (i=0; i<nprocs; i++) {
00539 sizes[i] = 0;
00540 }
00541 sizes[me] = ksize;
00542 char plus[2];
00543 strcpy(plus,"+");
00544 GA_Pgroup_igop(p_GAgrp,sizes,nprocs,plus);
00545 int *mapc = new int[nprocs];
00546 mapc[0] = 0;
00547 int total_values = sizes[0];
00548 for (i=1; i<nprocs; i++) {
00549 mapc[i] = mapc[i-1]+sizes[i-1];
00550 total_values += sizes[i];
00551 }
00552 if (total_values == 0) {
00553 delete [] sizes;
00554 delete [] mapc;
00555 return;
00556 }
00557
00558
00559 char *list, *ptr;
00560 if (ksize > 0) {
00561 list = new char[ksize*(nvals*sizeof(_bus_data_type)+sizeof(int))];
00562 ptr = list;
00563 for (i=0; i<ksize; i++) {
00564 ((int*)ptr)[0] = keys[i];
00565 ptr += sizeof(int);
00566 for (j=0; j<nvals; j++) {
00567 ((_bus_data_type*)ptr)[j] = (values[i])[j];
00568 }
00569 ptr += nvals*sizeof(_bus_data_type);
00570 }
00571 }
00572 int g_type = NGA_Register_type(nvals*sizeof(_bus_data_type)+sizeof(int));
00573
00574
00575 int lo, hi;
00576 lo = 0;
00577 for (i=0; i<me; i++) {
00578 lo += sizes[i];
00579 }
00580 hi = lo + sizes[me] - 1;
00581 int one = 1;
00582 int g_vals = GA_Create_handle();
00583 GA_Set_data(g_vals,one,&total_values,g_type);
00584
00585 GA_Set_pgroup(g_vals,p_GAgrp);
00586 if (!GA_Allocate(g_vals)) {
00587 char buf[256];
00588 sprintf(buf,"HashDistribution::distributeBusValues: Unable to allocate"
00589 " distributed array for storing values");
00590 printf("%s",buf);
00591 throw gridpack::Exception(buf);
00592 }
00593 if (lo <= hi) NGA_Put(g_vals, &lo, &hi, list, &one);
00594 GA_Pgroup_sync(p_GAgrp);
00595 NGA_Deregister_type(g_type);
00596 if (ksize > 0) delete [] list;
00597 delete [] mapc;
00598 delete [] sizes;
00599
00600
00601 int idx;
00602 int nbus = p_network->numBuses();
00603 std::multimap<int,int> hmap;
00604 for (i=0; i<nbus; i++) {
00605 idx = p_network->getOriginalBusIndex(i);
00606 hmap.insert(std::pair<int,int>(idx,i));
00607 }
00608 std::multimap<int,int>::iterator it;
00609
00610
00611 keys.clear();
00612 for (i=0; i<ksize; i++) {
00613 delete [] values[i];
00614 }
00615 values.clear();
00616 double delta = static_cast<double>(total_values)/static_cast<double>(nprocs);
00617 for (i = 0; i<nprocs; i++) {
00618 idx = (i+me)%nprocs;
00619 lo = static_cast<int>(delta*static_cast<double>(idx));
00620 if (idx<nprocs-1) {
00621 hi = static_cast<int>(delta*static_cast<double>(idx+1))-1;
00622 } else {
00623 hi = total_values-1;
00624 }
00625 int nsize = hi - lo + 1;
00626 if (lo <= hi) {
00627 list = new char[nsize*(nvals*sizeof(_bus_data_type)+sizeof(int))];
00628 if (lo<=hi) NGA_Get(g_vals, &lo, &hi, list, &one);
00629 int j, k;
00630 ptr = list;
00631 for (j=0; j<nsize; j++) {
00632 idx = ((int*)ptr)[0];
00633 ptr += sizeof(int);
00634 it = hmap.find(idx);
00635 if (it != hmap.end()) {
00636 while (it != hmap.upper_bound(idx)) {
00637 keys.push_back(it->second);
00638 _bus_data_type *data = new _bus_data_type[nvals];
00639 for (k=0; k<nvals; k++) {
00640 data[k] = ((_bus_data_type*)ptr)[k];
00641 }
00642 values.push_back(data);
00643 it++;
00644 }
00645 }
00646 ptr += nvals*sizeof(_bus_data_type);
00647 }
00648 delete [] list;
00649 }
00650 }
00651 GA_Destroy(g_vals);
00652 #else
00653 int nprocs = p_network->communicator().size();
00654 int me = p_network->communicator().rank();
00655
00656 int i,j;
00657
00658 std::vector<int> base_keys;
00659 std::set<int> key_check;
00660 std::set<int>::iterator itc;
00661 for (i=0; i<keys.size(); i++) {
00662 itc = key_check.find(keys[i]);
00663 if (itc == key_check.end()) {
00664 key_check.insert(keys[i]);
00665 base_keys.push_back(keys[i]);
00666 }
00667 }
00668 std::vector<int> procLoc;
00669
00670 p_indexHashMap->getValues(base_keys,procLoc);
00671
00672
00673
00674 std::multimap<int,int> keyMap;
00675 for (i=0; i<base_keys.size(); i++) {
00676 keyMap.insert(std::pair<int,int>(base_keys[i],procLoc[i]));
00677 }
00678 std::vector<_bus_data_type*> newValues;
00679 std::vector<int> newKeys;
00680 std::vector<int> destProcs;
00681 std::multimap<int,int>::iterator itk;
00682 _bus_data_type *dptr;
00683 for (i=0; i<values.size(); i++) {
00684 itk = keyMap.find(keys[i]);
00685 if (itk != keyMap.end()) {
00686 while (itk != keyMap.upper_bound(keys[i])) {
00687 dptr = new _bus_data_type[nvals];
00688 for (j=0; j<nvals; j++) {
00689 dptr[j] = (values[i])[j];
00690 }
00691 newValues.push_back(dptr);
00692 newKeys.push_back(keys[i]);
00693 destProcs.push_back(itk->second);
00694 itk++;
00695 }
00696 }
00697 }
00698
00699
00700 int nsize = newKeys.size();
00701 int ltop[nprocs];
00702 int ldest[nsize];
00703 int destNum[nprocs];
00704 for (i=0; i<nprocs; i++) {
00705 ltop[i] = -1;
00706 destNum[i] = 0;
00707 }
00708 for (i=0; i<nsize; i++) {
00709 ldest[i] = -1;
00710 }
00711 int iproc;
00712 for (i=0; i<nsize; i++) {
00713 iproc = destProcs[i];
00714 destNum[iproc]++;
00715 ldest[i] = ltop[iproc];
00716 ltop[iproc] = i;
00717 }
00718 #ifdef HASH_WITH_MPI
00719
00720
00721 int srcNum[nprocs];
00722 int ierr;
00723 int k;
00724 int one = 1;
00725 MPI_Comm comm = static_cast<MPI_Comm>(p_network->communicator());
00726 ierr = MPI_Alltoall(destNum,one,MPI_INT,srcNum,one,MPI_INT,comm);
00727
00728
00729
00730
00731 char *sendBuf;
00732 sendBuf = new char[newValues.size()
00733 * (sizeof(_bus_data_type)*nvals+sizeof(int))];
00734
00735 char *ptr = sendBuf;
00736 for (i=0; i<nprocs; i++) {
00737 j = ltop[i];
00738 if (j>=0) {
00739 while(j >= 0) {
00740 ((int*)ptr)[0] = newKeys[j];
00741 ptr += sizeof(int);
00742 dptr = (_bus_data_type*)ptr;
00743 for (k=0; k<nvals; k++) {
00744 dptr[k] = (newValues[j])[k];
00745 }
00746 j = ldest[j];
00747 ptr += nvals*sizeof(_bus_data_type);
00748 }
00749 }
00750 }
00751
00752
00753
00754 int elemsize = nvals*sizeof(_bus_data_type)+sizeof(int);
00755 int destOffset[nprocs];
00756 int srcOffset[nprocs];
00757 destOffset[0] = 0;
00758 srcOffset[0] = 0;
00759 for (i=1; i<nprocs; i++) {
00760 destOffset[i] = destOffset[i-1] + destNum[i-1];
00761 srcOffset[i] = srcOffset[i-1] + srcNum[i-1];
00762 }
00763 int nvalues = 0;
00764 for (i=0; i<nprocs; i++) {
00765 nvalues += srcNum[i];
00766 destOffset[i] = elemsize*destOffset[i];
00767 destNum[i] = elemsize*destNum[i];
00768 srcOffset[i] = elemsize*srcOffset[i];
00769 srcNum[i] = elemsize*srcNum[i];
00770 }
00771
00772
00773 char *recvBuf;
00774 recvBuf = new char[nvalues*(sizeof(_bus_data_type)*nvals+sizeof(int))];
00775
00776
00777 ierr = MPI_Alltoallv(sendBuf, destNum, destOffset, MPI_BYTE, recvBuf,
00778 srcNum, srcOffset, MPI_BYTE, comm);
00779 delete [] sendBuf;
00780
00781
00782
00783
00784 keys.clear();
00785 int vsize = values.size();
00786 for (i=0; i<vsize; i++) {
00787 delete [] values[i];
00788 }
00789 values.clear();
00790 int nbus = p_network->numBuses();
00791 std::multimap<int,int> idxMap;
00792 std::pair<int,int> idxPair;
00793
00794 for (i=0; i<nbus; i++) {
00795 idxPair = std::pair<int,int>(p_network->getOriginalBusIndex(i),i);
00796 idxMap.insert(idxPair);
00797 }
00798
00799
00800 std::multimap<int,int>::iterator it;
00801 _bus_data_type *rptr;
00802 int idx;
00803 ptr = recvBuf;
00804 for (i=0; i<nvalues; i++) {
00805 idx = ((int*)ptr)[0];
00806 ptr += sizeof(int);
00807 it = idxMap.find(idx);
00808 rptr = (_bus_data_type*)ptr;
00809 ptr += nvals*sizeof(_bus_data_type);
00810 if (it != idxMap.end()) {
00811 while (it != idxMap.upper_bound(idx)) {
00812 dptr = new _bus_data_type[nvals];
00813 for (j=0; j<nvals; j++) {
00814 dptr[j] = rptr[j];
00815 }
00816 keys.push_back(it->second);
00817 values.push_back(dptr);
00818 it++;
00819 }
00820 } else {
00821 printf("p[%d] Unresolved original bus index: %d\n",me,
00822 idx);
00823 }
00824 }
00825
00826 delete [] recvBuf;
00827 #else
00828
00829
00830 int g_numValues = GA_Create_handle();
00831 int dims;
00832 dims = nprocs;
00833 int one = 1;
00834 int blocks;
00835 blocks = 1;
00836 GA_Set_data(g_numValues,one,&dims,C_INT);
00837 GA_Set_chunk(g_numValues, &blocks);
00838 GA_Set_pgroup(g_numValues, p_GAgrp);
00839 GA_Allocate(g_numValues);
00840 GA_Zero(g_numValues);
00841 int r_offset[nprocs];
00842 for (j=0; j<nprocs; j++) {
00843 i = (j+me)%nprocs;
00844 if (destNum[i] > 0) {
00845 r_offset[i] = NGA_Read_inc(g_numValues,&i,destNum[i]);
00846 } else {
00847 r_offset[i] = 0;
00848 }
00849 }
00850 GA_Pgroup_sync(p_GAgrp);
00851
00852 int numValues[nprocs];
00853 int lo, hi;
00854 lo = 0;
00855 hi = nprocs-1;
00856 if (me == 0) {
00857 if (lo<=hi) NGA_Get(g_numValues,&lo,&hi,numValues,&one);
00858 } else {
00859 for (i=0; i<nprocs; i++) {
00860 numValues[i] = 0;
00861 }
00862 }
00863 char plus[2];
00864 strcpy(plus,"+");
00865 GA_Pgroup_igop(p_GAgrp,numValues,nprocs,plus);
00866 GA_Destroy(g_numValues);
00867
00868
00869
00870
00871 int dataSize = nvals*sizeof(_bus_data_type)+sizeof(int);
00872 int dtype = NGA_Register_type(dataSize);
00873
00874 int totalVals = 0;
00875 for (i=0; i<nprocs; i++) {
00876 r_offset[i] += totalVals;
00877 totalVals += numValues[i];
00878 }
00879 if (totalVals == 0) {
00880 NGA_Deregister_type(dtype);
00881 return;
00882 }
00883 int g_data = GA_Create_handle();
00884 dims = totalVals;
00885 GA_Set_data(g_data, one, &dims, dtype);
00886 GA_Set_pgroup(g_data,p_GAgrp);
00887 int mapc[nprocs];
00888 mapc[0] = 0;
00889 for (i=1; i<nprocs; i++) {
00890 mapc[i] = mapc[i-1] + numValues[i-1];
00891 }
00892 blocks = nprocs;
00893 GA_Set_irreg_distr(g_data,mapc,&blocks);
00894 GA_Allocate(g_data);
00895
00896
00897 char *bus_data, *ptr;
00898 int k;
00899 for (i=0; i<nprocs; i++) {
00900 j = ltop[i];
00901 if (j >= 0) {
00902 bus_data = new char[dataSize*destNum[i]];
00903 ptr = bus_data;
00904 while (j >= 0) {
00905 ((int*)ptr)[0] = newKeys[j];
00906 ptr += sizeof(int);
00907 dptr = (_bus_data_type*)ptr;
00908 for (k=0; k<nvals; k++) {
00909 dptr[k] = (newValues[j])[k];
00910 }
00911 ptr += nvals*sizeof(_bus_data_type);
00912 j = ldest[j];
00913 }
00914 lo = r_offset[i];
00915 hi = lo + destNum[i] - 1;
00916 if (lo<=hi) NGA_Put(g_data,&lo,&hi,bus_data,&one);
00917 delete [] bus_data;
00918 }
00919 }
00920
00921 GA_Pgroup_sync(p_GAgrp);
00922
00923 keys.clear();
00924 int vsize = values.size();
00925 for (i=0; i<vsize; i++) {
00926 delete [] values[i];
00927 }
00928 values.clear();
00929 int nbus = p_network->numBuses();
00930 std::multimap<int,int> idxMap;
00931 std::pair<int,int> idxPair;
00932
00933 for (i=0; i<nbus; i++) {
00934 idxPair = std::pair<int,int>(p_network->getOriginalBusIndex(i),i);
00935 idxMap.insert(idxPair);
00936 }
00937
00938
00939 int ndata = numValues[me];
00940 lo = mapc[me];
00941 hi = lo + ndata - 1;
00942 if (lo<=hi) NGA_Access(g_data,&lo,&hi,&bus_data,&one);
00943 std::multimap<int,int>::iterator it;
00944 int idx;
00945 ptr = bus_data;
00946 _bus_data_type *rptr;
00947 for (i=0; i<ndata; i++) {
00948 idx = ((int*)ptr)[0];
00949 ptr += sizeof(int);
00950 it = idxMap.find(idx);
00951 rptr = (_bus_data_type*)ptr;
00952 ptr += nvals*sizeof(_bus_data_type);
00953 if (it != idxMap.end()) {
00954 while (it != idxMap.upper_bound(idx)) {
00955 keys.push_back(it->second);
00956 dptr = new _bus_data_type[nvals];
00957 for (j=0; j<nvals; j++) {
00958 dptr[j] = rptr[j];
00959 }
00960 values.push_back(dptr);
00961 it++;
00962 }
00963 } else {
00964 printf("p[%d] Unresolved original bus index: %d\n",me,
00965 idx);
00966 }
00967 }
00968 if (lo<=hi) NGA_Release(g_data,&lo,&hi);
00969 GA_Destroy(g_data);
00970 #endif
00971 #endif
00972 }
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983 void distributeBranchValues(std::vector<std::pair<int,int> > &keys,
00984 std::vector<int> &branch_ids,
00985 std::vector<_branch_data_type> &values)
00986 {
00987 #ifdef SYSTOLIC
00988 int ksize = keys.size();
00989 int vsize = values.size();
00990 int me = GA_Pgroup_nodeid(p_GAgrp);
00991 int nprocs = GA_Pgroup_nnodes(p_GAgrp);
00992 if (vsize != ksize) {
00993 char buf[256];
00994 sprintf(buf,"p[%d] HashDistribution::distributeBranchValues ERROR: length"
00995 " of keys and values arrays don't match ksize: %d vsize: %d\n",
00996 me,ksize,vsize);
00997 printf("%s",buf);
00998 throw gridpack::Exception(buf);
00999 }
01000
01001
01002 int i;
01003 int *sizes = new int[nprocs];
01004 for (i=0; i<nprocs; i++) {
01005 sizes[i] = 0;
01006 }
01007 sizes[me] = ksize;
01008 char plus[2];
01009 strcpy(plus,"+");
01010 GA_Pgroup_igop(p_GAgrp,sizes,nprocs,plus);
01011 int *mapc = new int[nprocs];
01012 mapc[0] = 0;
01013 int total_values = sizes[0];
01014 for (i=1; i<nprocs; i++) {
01015 mapc[i] = mapc[i-1]+sizes[i-1];
01016 total_values += sizes[i];
01017 }
01018 if (total_values == 0) {
01019 delete [] sizes;
01020 delete [] mapc;
01021 return;
01022 }
01023
01024
01025 branch_data_pair *list;
01026 if (ksize > 0) {
01027 list = new branch_data_pair[ksize];
01028 for (i=0; i<ksize; i++) {
01029 list[i].idx1 = keys[i].first;
01030 list[i].idx2 = keys[i].second;
01031 list[i].data = values[i];
01032 }
01033 }
01034 int g_type = NGA_Register_type(p_size_branch_data);
01035
01036
01037 int lo, hi;
01038 lo = 0;
01039 for (i=0; i<me; i++) {
01040 lo += sizes[i];
01041 }
01042 hi = lo + sizes[me] - 1;
01043 int one = 1;
01044 int g_vals = GA_Create_handle();
01045 GA_Set_data(g_vals,one,&total_values,g_type);
01046
01047 GA_Set_pgroup(g_vals,p_GAgrp);
01048 if (!GA_Allocate(g_vals)) {
01049 char buf[256];
01050 sprintf(buf,"HashDistribution::distributeBranchValues: Unable to allocate"
01051 " distributed array for storing values");
01052 printf("%s",buf);
01053 throw gridpack::Exception(buf);
01054 }
01055 if (lo <= hi) NGA_Put(g_vals, &lo, &hi, list, &one);
01056 GA_Pgroup_sync(p_GAgrp);
01057 NGA_Deregister_type(g_type);
01058 if (ksize > 0) delete [] list;
01059 delete [] mapc;
01060 delete [] sizes;
01061
01062
01063 int idx,idx1,idx2;
01064 int nbranch = p_network->numBranches();
01065 std::multimap<std::pair<int,int>,int> hmap;
01066 for (i=0; i<nbranch; i++) {
01067 p_network->getOriginalBranchEndpoints(i,&idx1,&idx2);
01068 hmap.insert(std::pair<std::pair<int,int>,int>(std::pair<int,int>(idx1,idx2),i));
01069 }
01070 std::multimap<std::pair<int,int>,int>::iterator it;
01071
01072
01073 branch_ids.clear();
01074 values.clear();
01075 double delta = static_cast<double>(total_values)/static_cast<double>(nprocs);
01076 for (i = 0; i<nprocs; i++) {
01077 idx = (i+me)%nprocs;
01078 lo = static_cast<int>(delta*static_cast<double>(idx));
01079 if (idx<nprocs-1) {
01080 hi = static_cast<int>(delta*static_cast<double>(idx+1))-1;
01081 } else {
01082 hi = total_values-1;
01083 }
01084 int nsize = hi - lo + 1;
01085 if (lo <= hi) {
01086 list = new branch_data_pair[nsize];
01087 if (lo<=hi) NGA_Get(g_vals, &lo, &hi, list, &one);
01088 int j;
01089 std::pair<int,int> key;
01090 for (j=0; j<nsize; j++) {
01091 key = std::pair<int,int>(list[j].idx1,list[j].idx2);
01092 it = hmap.find(key);
01093 if (it != hmap.end()) {
01094 while(it != hmap.upper_bound(key)) {
01095 branch_ids.push_back(it->second);
01096 values.push_back(list[j].data);
01097 it++;
01098 }
01099 }
01100 }
01101 delete [] list;
01102 }
01103 }
01104 GA_Destroy(g_vals);
01105 #else
01106 int nprocs = p_network->communicator().size();
01107 int me = p_network->communicator().rank();
01108
01109 int i,j;
01110
01111 std::vector<std::pair<int,int> > base_keys;
01112 std::set<std::pair<int,int> > key_check;
01113 std::set<std::pair<int,int> >::iterator itc;
01114 for (i=0; i<keys.size(); i++) {
01115 itc = key_check.find(keys[i]);
01116 if (itc == key_check.end()) {
01117 key_check.insert(keys[i]);
01118 base_keys.push_back(keys[i]);
01119 }
01120 }
01121 std::vector<int> procLoc;
01122
01123 p_indexHashMap->getValues(base_keys,procLoc);
01124
01125
01126
01127 std::multimap<std::pair<int,int>,int> keyMap;
01128 for (i=0; i<base_keys.size(); i++) {
01129 keyMap.insert(std::pair<std::pair<int,int>,int>(base_keys[i],procLoc[i]));
01130 }
01131 std::vector<_branch_data_type> newValues;
01132 std::vector<std::pair<int,int> > newKeys;
01133 std::vector<int> destProcs;
01134 j = 0;
01135 std::multimap<std::pair<int,int>,int>::iterator itk;
01136 for (i=0; i<values.size(); i++) {
01137 itk = keyMap.find(keys[i]);
01138 if (itk != keyMap.end()) {
01139 while (itk != keyMap.upper_bound(keys[i])) {
01140 newValues.push_back(values[i]);
01141 newKeys.push_back(keys[i]);
01142 destProcs.push_back(itk->second);
01143 itk++;
01144 }
01145 }
01146 }
01147
01148
01149 int nsize = newKeys.size();
01150 int ltop[nprocs];
01151 int ldest[nsize];
01152 int destNum[nprocs];
01153 for (i=0; i<nprocs; i++) {
01154 ltop[i] = -1;
01155 destNum[i] = 0;
01156 }
01157 for (i=0; i<nsize; i++) {
01158 ldest[i] = -1;
01159 }
01160 int iproc;
01161 for (i=0; i<nsize; i++) {
01162 iproc = destProcs[i];
01163 destNum[iproc]++;
01164 ldest[i] = ltop[iproc];
01165 ltop[iproc] = i;
01166 }
01167 #ifdef HASH_WITH_MPI
01168
01169
01170 int srcNum[nprocs];
01171 int ierr;
01172 int one = 1;
01173 MPI_Comm comm = static_cast<MPI_Comm>(p_network->communicator());
01174 ierr = MPI_Alltoall(destNum,one,MPI_INT,srcNum,one,MPI_INT,comm);
01175
01176
01177
01178
01179 branch_data_pair *sendBuf;
01180 sendBuf = new branch_data_pair[newValues.size()];
01181
01182 int icnt = 0;
01183 for (i=0; i<nprocs; i++) {
01184 j = ltop[i];
01185 if (j>=0) {
01186 while(j >= 0) {
01187 sendBuf[icnt].idx1 = newKeys[j].first;
01188 sendBuf[icnt].idx2 = newKeys[j].second;
01189 sendBuf[icnt].data = newValues[j];
01190 j = ldest[j];
01191 icnt++;
01192 }
01193 }
01194 }
01195
01196
01197
01198 int elemsize = sizeof(branch_data_pair);
01199 int destOffset[nprocs];
01200 int srcOffset[nprocs];
01201 destOffset[0] = 0;
01202 srcOffset[0] = 0;
01203 for (i=1; i<nprocs; i++) {
01204 destOffset[i] = destOffset[i-1] + destNum[i-1];
01205 srcOffset[i] = srcOffset[i-1] + srcNum[i-1];
01206 }
01207 int nvalues = 0;
01208 for (i=0; i<nprocs; i++) {
01209 nvalues += srcNum[i];
01210 destOffset[i] = elemsize*destOffset[i];
01211 destNum[i] = elemsize*destNum[i];
01212 srcOffset[i] = elemsize*srcOffset[i];
01213 srcNum[i] = elemsize*srcNum[i];
01214 }
01215
01216
01217 branch_data_pair *recvBuf;
01218 recvBuf = new branch_data_pair[nvalues];
01219
01220
01221 ierr = MPI_Alltoallv(sendBuf, destNum, destOffset, MPI_BYTE, recvBuf,
01222 srcNum, srcOffset, MPI_BYTE, comm);
01223 delete [] sendBuf;
01224
01225
01226
01227
01228 values.clear();
01229 branch_ids.clear();
01230 int nbranch = p_network->numBranches();
01231 std::multimap<std::pair<int,int>,int> idxMap;
01232 std::pair<std::pair<int,int>,int> idxPair;
01233
01234 int idx1, idx2;
01235 std::pair<int,int> key;
01236 for (i=0; i<nbranch; i++) {
01237 p_network->getOriginalBranchEndpoints(i,&idx1,&idx2);
01238 key = std::pair<int,int>(idx1,idx2);
01239 idxPair = std::pair<std::pair<int,int>,int>(key,i);
01240 idxMap.insert(idxPair);
01241 }
01242
01243
01244 std::multimap<std::pair<int,int>,int>::iterator it;
01245 for (i=0; i<nvalues; i++) {
01246 key = std::pair<int,int>(recvBuf[i].idx1,recvBuf[i].idx2);
01247 it = idxMap.find(key);
01248 if (it != idxMap.end()) {
01249 while (it != idxMap.upper_bound(key)) {
01250 branch_ids.push_back(it->second);
01251 values.push_back(recvBuf[i].data);
01252 it++;
01253 }
01254 } else {
01255 printf("p[%d] Unresolved original branch index: < %d, %d>\n",me,
01256 recvBuf[i].idx1,recvBuf[i].idx2);
01257 }
01258 }
01259
01260 delete [] recvBuf;
01261 #else
01262
01263
01264 int g_numValues = GA_Create_handle();
01265 int dims;
01266 dims = nprocs;
01267 int one = 1;
01268 int blocks;
01269 blocks = 1;
01270 GA_Set_data(g_numValues,one,&dims,C_INT);
01271 GA_Set_chunk(g_numValues, &blocks);
01272 GA_Set_pgroup(g_numValues, p_GAgrp);
01273 GA_Allocate(g_numValues);
01274 GA_Zero(g_numValues);
01275 int r_offset[nprocs];
01276 for (j=0; j<nprocs; j++) {
01277 i = (j+me)%nprocs;
01278 if (destNum[i] > 0) {
01279 r_offset[i] = NGA_Read_inc(g_numValues,&i,destNum[i]);
01280 } else {
01281 r_offset[i] = 0;
01282 }
01283 }
01284 GA_Pgroup_sync(p_GAgrp);
01285
01286 int numValues[nprocs];
01287 int lo, hi;
01288 lo = 0;
01289 hi = nprocs-1;
01290 if (me == 0) {
01291 if (lo<=hi) NGA_Get(g_numValues,&lo,&hi,numValues,&one);
01292 } else {
01293 for (i=0; i<nprocs; i++) {
01294 numValues[i] = 0;
01295 }
01296 }
01297 char plus[2];
01298 strcpy(plus,"+");
01299 GA_Pgroup_igop(p_GAgrp,numValues,nprocs,plus);
01300 GA_Destroy(g_numValues);
01301
01302
01303
01304
01305 int dtype = NGA_Register_type(sizeof(branch_data_pair));
01306
01307 int totalVals = 0;
01308 for (i=0; i<nprocs; i++) {
01309 r_offset[i] += totalVals;
01310 totalVals += numValues[i];
01311 }
01312 if (totalVals == 0) {
01313 NGA_Deregister_type(dtype);
01314 return;
01315 }
01316 int g_data = GA_Create_handle();
01317 dims = totalVals;
01318 GA_Set_data(g_data, one, &dims, dtype);
01319 GA_Set_pgroup(g_data,p_GAgrp);
01320 int mapc[nprocs];
01321 mapc[0] = 0;
01322 for (i=1; i<nprocs; i++) {
01323 mapc[i] = mapc[i-1] + numValues[i-1];
01324 }
01325 blocks = nprocs;
01326 GA_Set_irreg_distr(g_data,mapc,&blocks);
01327 GA_Allocate(g_data);
01328
01329
01330
01331 branch_data_pair *branch_data;
01332 int ncnt;
01333 for (i=0; i<nprocs; i++) {
01334 j = ltop[i];
01335 ncnt = 0;
01336 if (j >= 0) {
01337 branch_data = new branch_data_pair[destNum[i]];
01338 while (j >= 0) {
01339 branch_data[ncnt].idx1 = newKeys[j].first;
01340 branch_data[ncnt].idx2 = newKeys[j].second;
01341 branch_data[ncnt].data = newValues[j];
01342 j = ldest[j];
01343 ncnt++;
01344 }
01345 lo = r_offset[i];
01346 hi = lo + destNum[i] - 1;
01347 if (lo<=hi) NGA_Put(g_data,&lo,&hi,branch_data,&one);
01348 delete [] branch_data;
01349 }
01350 }
01351
01352 GA_Pgroup_sync(p_GAgrp);
01353
01354 keys.clear();
01355 values.clear();
01356 int nbranch = p_network->numBranches();
01357 std::multimap<std::pair<int,int>,int> idxMap;
01358 std::pair<std::pair<int,int>,int> idxPair;
01359
01360 int idx1, idx2;
01361 for (i=0; i<nbranch; i++) {
01362 p_network->getOriginalBranchEndpoints(i,&idx1,&idx2);
01363 idxPair = std::pair<std::pair<int,int>,int>(std::pair<int,int>(idx1,idx2),i);
01364 idxMap.insert(idxPair);
01365 }
01366
01367
01368 int ndata = numValues[me];
01369 lo = mapc[me];
01370 hi = lo + ndata - 1;
01371 if (lo<=hi) NGA_Access(g_data,&lo,&hi,&branch_data,&one);
01372 std::multimap<std::pair<int,int>,int>::iterator it;
01373 std::pair<int,int> key;
01374 for (i=0; i<ndata; i++) {
01375 key = std::pair<int,int>(branch_data[i].idx1,branch_data[i].idx2);
01376 it = idxMap.find(key);
01377 if (it != idxMap.end()) {
01378 while (it != idxMap.upper_bound(key)) {
01379 branch_ids.push_back(it->second);
01380 values.push_back(branch_data[i].data);
01381 it++;
01382 }
01383 } else {
01384 printf("p[%d] Unresolved original branch index: < %d, %d >\n",me,
01385 branch_data[i].idx1,branch_data[i].idx2);
01386 }
01387 }
01388 if (lo<=hi) NGA_Release(g_data,&lo,&hi);
01389 GA_Destroy(g_data);
01390 #endif
01391 #endif
01392 }
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404 void distributeBranchValues(std::vector<std::pair<int,int> > &keys,
01405 std::vector<int> &branch_ids,
01406 std::vector<_branch_data_type*> &values, int nvals)
01407 {
01408 #ifdef SYSTOLIC
01409 int ksize = keys.size();
01410 int vsize = values.size();
01411 int me = GA_Pgroup_nodeid(p_GAgrp);
01412 int nprocs = GA_Pgroup_nnodes(p_GAgrp);
01413 if (vsize != ksize) {
01414 char buf[256];
01415 sprintf(buf,"p[%d] HashDistribution::distributeBranchValues ERROR: length"
01416 " of keys and values arrays don't match ksize: %d vsize: %d\n",
01417 me,ksize,vsize);
01418 printf("%s",buf);
01419 throw gridpack::Exception(buf);
01420 }
01421
01422
01423 int i, j;
01424 int *sizes = new int[nprocs];
01425 for (i=0; i<nprocs; i++) {
01426 sizes[i] = 0;
01427 }
01428 sizes[me] = ksize;
01429 char plus[2];
01430 strcpy(plus,"+");
01431 GA_Pgroup_igop(p_GAgrp,sizes,nprocs,plus);
01432 int *mapc = new int[nprocs];
01433 mapc[0] = 0;
01434 int total_values = sizes[0];
01435 for (i=1; i<nprocs; i++) {
01436 mapc[i] = mapc[i-1]+sizes[i-1];
01437 total_values += sizes[i];
01438 }
01439 if (total_values == 0) {
01440 delete [] sizes;
01441 delete [] mapc;
01442 return;
01443 }
01444
01445
01446 char *list, *ptr;
01447 if (ksize > 0) {
01448 list = new char[ksize*(nvals*sizeof(_branch_data_type)+2*sizeof(int))];
01449 ptr = list;
01450 for (i=0; i<ksize; i++) {
01451 ((int*)ptr)[0] = keys[i].first;
01452 ((int*)ptr)[1] = keys[i].second;
01453 ptr += 2*sizeof(int);
01454 for (j=0; j<nvals; j++) {
01455 ((_branch_data_type*)ptr)[j] = (values[i])[j];
01456 }
01457 ptr += nvals*sizeof(_branch_data_type);
01458 }
01459 }
01460 int g_type = NGA_Register_type(nvals*sizeof(_branch_data_type)+2*sizeof(int));
01461
01462
01463 int lo, hi;
01464 lo = 0;
01465 for (i=0; i<me; i++) {
01466 lo += sizes[i];
01467 }
01468 hi = lo + sizes[me] - 1;
01469 int one = 1;
01470 int g_vals = GA_Create_handle();
01471 GA_Set_data(g_vals,one,&total_values,g_type);
01472
01473 GA_Set_pgroup(g_vals,p_GAgrp);
01474 if (!GA_Allocate(g_vals)) {
01475 char buf[256];
01476 sprintf(buf,"HashDistribution::distributeBranchValues: Unable to allocate"
01477 " distributed array for storing values");
01478 printf("%s",buf);
01479 throw gridpack::Exception(buf);
01480 }
01481 if (lo <= hi) NGA_Put(g_vals, &lo, &hi, list, &one);
01482 GA_Pgroup_sync(p_GAgrp);
01483 NGA_Deregister_type(g_type);
01484 if (ksize > 0) delete [] list;
01485 delete [] mapc;
01486 delete [] sizes;
01487
01488
01489 int idx,idx1,idx2;
01490 int nbranch = p_network->numBranches();
01491 std::multimap<std::pair<int,int>,int> hmap;
01492 for (i=0; i<nbranch; i++) {
01493 p_network->getOriginalBranchEndpoints(i,&idx1,&idx2);
01494 hmap.insert(std::pair<std::pair<int,int>,int>(std::pair<int,int>(idx1,idx2),i));
01495 }
01496 std::multimap<std::pair<int,int>,int>::iterator it;
01497
01498
01499 branch_ids.clear();
01500 for (i=0; i<ksize; i++) {
01501 delete [] values[i];
01502 }
01503 values.clear();
01504 double delta = static_cast<double>(total_values)/static_cast<double>(nprocs);
01505 for (i = 0; i<nprocs; i++) {
01506 idx = (i+me)%nprocs;
01507 lo = static_cast<int>(delta*static_cast<double>(idx));
01508 if (idx<nprocs-1) {
01509 hi = static_cast<int>(delta*static_cast<double>(idx+1))-1;
01510 } else {
01511 hi = total_values-1;
01512 }
01513 int nsize = hi - lo + 1;
01514 if (lo <= hi) {
01515 list = new char[nsize*(nvals*sizeof(_branch_data_type)+2*sizeof(int))];
01516 if (lo<=hi) NGA_Get(g_vals, &lo, &hi, list, &one);
01517 int j, k;
01518 std::pair<int,int> key;
01519 ptr = list;
01520 for (j=0; j<nsize; j++) {
01521 key = std::pair<int,int>(((int*)ptr)[0],((int*)ptr)[1]);
01522 ptr += 2*sizeof(int);
01523 it = hmap.find(key);
01524 if (it != hmap.end()) {
01525 while(it != hmap.upper_bound(key)) {
01526 branch_ids.push_back(it->second);
01527 _branch_data_type *data = new _branch_data_type[nvals];
01528 for (k=0; k<nvals; k++) {
01529 data[k] = ((_branch_data_type*)ptr)[k];
01530 }
01531 values.push_back(data);
01532 it++;
01533 }
01534 }
01535 ptr += nvals*sizeof(_branch_data_type);
01536 }
01537 delete [] list;
01538 }
01539 }
01540 GA_Destroy(g_vals);
01541 #else
01542 int nprocs = p_network->communicator().size();
01543 int me = p_network->communicator().rank();
01544
01545 int i,j;
01546
01547 std::vector<std::pair<int,int> > base_keys;
01548 std::set<std::pair<int,int> > key_check;
01549 std::set<std::pair<int,int> >::iterator itc;
01550 for (i=0; i<keys.size(); i++) {
01551 itc = key_check.find(keys[i]);
01552 if (itc == key_check.end()) {
01553 key_check.insert(keys[i]);
01554 base_keys.push_back(keys[i]);
01555 }
01556 }
01557 std::vector<int> procLoc;
01558
01559 p_indexHashMap->getValues(base_keys,procLoc);
01560
01561
01562
01563 std::multimap<std::pair<int,int>,int> keyMap;
01564 for (i=0; i<base_keys.size(); i++) {
01565 keyMap.insert(std::pair<std::pair<int,int>,int>(base_keys[i],procLoc[i]));
01566 }
01567 std::vector<_branch_data_type*> newValues;
01568 std::vector<std::pair<int,int> > newKeys;
01569 std::vector<int> destProcs;
01570 std::multimap<std::pair<int,int>,int>::iterator itk;
01571 _branch_data_type *dptr;
01572 for (i=0; i<values.size(); i++) {
01573 itk = keyMap.find(keys[i]);
01574 if (itk != keyMap.end()) {
01575 while (itk != keyMap.upper_bound(keys[i])) {
01576 dptr = new _branch_data_type[nvals];
01577 for (j=0; j<nvals; j++) {
01578 dptr[j] = (values[i])[j];
01579 }
01580 newValues.push_back(values[i]);
01581 newKeys.push_back(keys[i]);
01582 destProcs.push_back(itk->second);
01583 itk++;
01584 }
01585 }
01586 }
01587
01588
01589 int nsize = newKeys.size();
01590 int ltop[nprocs];
01591 int ldest[nsize];
01592 int destNum[nprocs];
01593 for (i=0; i<nprocs; i++) {
01594 ltop[i] = -1;
01595 destNum[i] = 0;
01596 }
01597 for (i=0; i<nsize; i++) {
01598 ldest[i] = -1;
01599 }
01600 int iproc;
01601 for (i=0; i<nsize; i++) {
01602 iproc = destProcs[i];
01603 destNum[iproc]++;
01604 ldest[i] = ltop[iproc];
01605 ltop[iproc] = i;
01606 }
01607 #ifdef HASH_WITH_MPI
01608
01609
01610 int srcNum[nprocs];
01611 int ierr;
01612 int one = 1;
01613 MPI_Comm comm = static_cast<MPI_Comm>(p_network->communicator());
01614 ierr = MPI_Alltoall(destNum,one,MPI_INT,srcNum,one,MPI_INT,comm);
01615
01616
01617
01618
01619 char *sendBuf;
01620 sendBuf = new char[newValues.size()
01621 * (sizeof(_branch_data_type)*nvals+2*sizeof(int))];
01622
01623 char *ptr = sendBuf;
01624 int k;
01625 for (i=0; i<nprocs; i++) {
01626 j = ltop[i];
01627 if (j>=0) {
01628 while(j >= 0) {
01629 ((int*)ptr)[0] = newKeys[j].first;
01630 ((int*)ptr)[1] = newKeys[j].second;
01631 ptr += 2*sizeof(int);
01632 dptr = (_branch_data_type*)ptr;
01633 for (k=0; k<nvals; k++) {
01634 dptr[k] = (newValues[j])[k];
01635 }
01636 j = ldest[j];
01637 ptr += nvals*sizeof(_branch_data_type);
01638 }
01639 }
01640 }
01641
01642
01643
01644 int elemsize = nvals*sizeof(_branch_data_type)+2*sizeof(int);
01645 int destOffset[nprocs];
01646 int srcOffset[nprocs];
01647 destOffset[0] = 0;
01648 srcOffset[0] = 0;
01649 for (i=1; i<nprocs; i++) {
01650 destOffset[i] = destOffset[i-1] + destNum[i-1];
01651 srcOffset[i] = srcOffset[i-1] + srcNum[i-1];
01652 }
01653 int nvalues = 0;
01654 for (i=0; i<nprocs; i++) {
01655 nvalues += srcNum[i];
01656 destOffset[i] = elemsize*destOffset[i];
01657 destNum[i] = elemsize*destNum[i];
01658 srcOffset[i] = elemsize*srcOffset[i];
01659 srcNum[i] = elemsize*srcNum[i];
01660 }
01661
01662
01663 char *recvBuf;
01664 recvBuf = new char[nvalues*(sizeof(_branch_data_type)*nvals+2*sizeof(int))];
01665
01666
01667 ierr = MPI_Alltoallv(sendBuf, destNum, destOffset, MPI_BYTE, recvBuf,
01668 srcNum, srcOffset, MPI_BYTE, comm);
01669 delete [] sendBuf;
01670
01671
01672
01673
01674 int vsize = values.size();
01675 for (i=0; i<vsize; i++) {
01676 delete [] values[i];
01677 }
01678 values.clear();
01679 branch_ids.clear();
01680 int nbranch = p_network->numBranches();
01681 std::multimap<std::pair<int,int>,int> idxMap;
01682 std::pair<std::pair<int,int>,int> idxPair;
01683
01684 int idx1, idx2;
01685 std::pair<int,int> key;
01686 for (i=0; i<nbranch; i++) {
01687 p_network->getOriginalBranchEndpoints(i,&idx1,&idx2);
01688 key = std::pair<int,int>(idx1,idx2);
01689 idxPair = std::pair<std::pair<int,int>,int>(key,i);
01690 idxMap.insert(idxPair);
01691 }
01692
01693
01694 std::multimap<std::pair<int,int>,int>::iterator it;
01695 _branch_data_type *rptr;
01696 ptr = recvBuf;
01697 for (i=0; i<nvalues; i++) {
01698 key = std::pair<int,int>(((int*)ptr)[0], ((int*)ptr)[1]);
01699 ptr += 2*sizeof(int);
01700 it = idxMap.find(key);
01701 rptr = (_branch_data_type*)ptr;
01702 ptr += nvals*sizeof(_branch_data_type);
01703 if (it != idxMap.end()) {
01704 while (it != idxMap.upper_bound(key)) {
01705 dptr = new _branch_data_type[nvals];
01706 for (j=0; j<nvals; j++) {
01707 dptr[j] = rptr[j];
01708 }
01709 branch_ids.push_back(it->second);
01710 values.push_back(dptr);
01711 it++;
01712 }
01713 } else {
01714 printf("p[%d] Unresolved original branch index: < %d, %d>\n",me,
01715 key.first,key.second);
01716 }
01717 }
01718
01719 delete [] recvBuf;
01720 #else
01721
01722
01723 int g_numValues = GA_Create_handle();
01724 int dims;
01725 dims = nprocs;
01726 int one = 1;
01727 int blocks;
01728 blocks = 1;
01729 GA_Set_data(g_numValues,one,&dims,C_INT);
01730 GA_Set_chunk(g_numValues, &blocks);
01731 GA_Set_pgroup(g_numValues, p_GAgrp);
01732 GA_Allocate(g_numValues);
01733 GA_Zero(g_numValues);
01734 int r_offset[nprocs];
01735 for (j=0; j<nprocs; j++) {
01736 i = (j+me)%nprocs;
01737 if (destNum[i] > 0) {
01738 r_offset[i] = NGA_Read_inc(g_numValues,&i,destNum[i]);
01739 } else {
01740 r_offset[i] = 0;
01741 }
01742 }
01743 GA_Pgroup_sync(p_GAgrp);
01744
01745 int numValues[nprocs];
01746 int lo, hi;
01747 lo = 0;
01748 hi = nprocs-1;
01749 if (me == 0) {
01750 if (lo<=hi) NGA_Get(g_numValues,&lo,&hi,numValues,&one);
01751 } else {
01752 for (i=0; i<nprocs; i++) {
01753 numValues[i] = 0;
01754 }
01755 }
01756 char plus[2];
01757 strcpy(plus,"+");
01758 GA_Pgroup_igop(p_GAgrp,numValues,nprocs,plus);
01759 GA_Destroy(g_numValues);
01760
01761
01762
01763
01764 int dataSize = nvals*sizeof(_branch_data_type)+2*sizeof(int);
01765 int dtype = NGA_Register_type(dataSize);
01766
01767 int totalVals = 0;
01768 for (i=0; i<nprocs; i++) {
01769 r_offset[i] += totalVals;
01770 totalVals += numValues[i];
01771 }
01772 if (totalVals == 0) {
01773 NGA_Deregister_type(dtype);
01774 return;
01775 }
01776 int g_data = GA_Create_handle();
01777 dims = totalVals;
01778 GA_Set_data(g_data, one, &dims, dtype);
01779 GA_Set_pgroup(g_data,p_GAgrp);
01780 int mapc[nprocs];
01781 mapc[0] = 0;
01782 for (i=1; i<nprocs; i++) {
01783 mapc[i] = mapc[i-1] + numValues[i-1];
01784 }
01785 blocks = nprocs;
01786 GA_Set_irreg_distr(g_data,mapc,&blocks);
01787 GA_Allocate(g_data);
01788
01789
01790
01791 char *branch_data, *ptr;
01792 int k;
01793 for (i=0; i<nprocs; i++) {
01794 j = ltop[i];
01795 if (j >= 0) {
01796 branch_data = new char[dataSize*destNum[i]];
01797 ptr = branch_data;
01798 while (j >= 0) {
01799 ((int*)ptr)[0] = newKeys[j].first;
01800 ((int*)ptr)[1] = newKeys[j].second;
01801 ptr += 2*sizeof(int);
01802 dptr = (_branch_data_type*)ptr;
01803 for (k=0; k<nvals; k++) {
01804 dptr[k] = (newValues[j])[k];
01805 }
01806 ptr += nvals*sizeof(_branch_data_type);
01807 j = ldest[j];
01808 }
01809 lo = r_offset[i];
01810 hi = lo + destNum[i] - 1;
01811 if (lo<=hi) NGA_Put(g_data,&lo,&hi,branch_data,&one);
01812 delete [] branch_data;
01813 }
01814 }
01815
01816 GA_Pgroup_sync(p_GAgrp);
01817
01818 keys.clear();
01819 int vsize = values.size();
01820 for (i=0; i<vsize; i++) {
01821 delete [] values[i];
01822 }
01823 values.clear();
01824 int nbranch = p_network->numBranches();
01825 std::multimap<std::pair<int,int>,int> idxMap;
01826 std::pair<std::pair<int,int>,int> idxPair;
01827
01828 int idx1, idx2;
01829 for (i=0; i<nbranch; i++) {
01830 p_network->getOriginalBranchEndpoints(i,&idx1,&idx2);
01831 idxPair = std::pair<std::pair<int,int>,int>(std::pair<int,int>(idx1,idx2),i);
01832 idxMap.insert(idxPair);
01833 }
01834
01835
01836 int ndata = numValues[me];
01837 lo = mapc[me];
01838 hi = lo + ndata - 1;
01839 if (lo<=hi) NGA_Access(g_data,&lo,&hi,&branch_data,&one);
01840 std::multimap<std::pair<int,int>,int>::iterator it;
01841 std::pair<int,int> key;
01842 ptr = branch_data;
01843 _branch_data_type *rptr;
01844 for (i=0; i<ndata; i++) {
01845 key = std::pair<int,int>(((int*)ptr)[0], ((int*)ptr)[1]);
01846 ptr += 2*sizeof(int);
01847 it = idxMap.find(key);
01848 rptr = (_branch_data_type*)ptr;
01849 ptr += nvals*sizeof(_branch_data_type);
01850 if (it != idxMap.end()) {
01851 while (it != idxMap.upper_bound(key)) {
01852 branch_ids.push_back(it->second);
01853 dptr = new _branch_data_type[nvals];
01854 for (j=0; j<nvals; j++) {
01855 dptr[j] = rptr[j];
01856 }
01857 values.push_back(dptr);
01858 it++;
01859 }
01860 } else {
01861 printf("p[%d] Unresolved original branch index: < %d, %d >\n",me,
01862 key.first,key.second);
01863 }
01864 }
01865 if (lo<=hi) NGA_Release(g_data,&lo,&hi);
01866 GA_Destroy(g_data);
01867 #endif
01868 #endif
01869 }
01870
01871 private:
01872
01873
01874 boost::shared_ptr<gridpack::hash_map::GlobalIndexHashMap> p_indexHashMap;
01875
01876 NetworkPtr p_network;
01877
01878 int p_size_bus_data;
01879 int p_size_branch_data;
01880
01881 int p_GAgrp;
01882
01883 };
01884
01885
01886 }
01887 }
01888
01889 #endif
01890